home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Graphics 2D / ScreenDump / PictInfoTest.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  12.8 KB  |  514 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        PictInfoTest.c
  3.  
  4.     Contains:    Sample to demonstrate using the Picture Utilities Package
  5.     
  6.                 The guts of this is in the window creation function: DoCreateWindow( PicHandle thePicture )
  7.     
  8.                 DoCreateWindow is passed a picture handle and if the global gUsePictPalette is set it
  9.                 will use the pict utils package (PUP) to get the color table stored in the pict.  You could 
  10.                 this source to sample direct color images, but to keep things as clear as possible this
  11.                 application only deals with 8 bit images.
  12.     
  13.                 We use the PUP to get the color table for the image.  This is passed into NewGWorld and it
  14.                 is also used to create a palette that is attached to the window.
  15.     
  16.                 Note that we use PUP to sample the image that was stored in the file.  We interrogate a
  17.                 PicHandle read directly from the file.  There are also routines for sampling PixMaps,
  18.                 but dont forget that if you are in an indexed color environment, and you sample a PixMap, 
  19.                 if you didnt set up the color environment when your first created the PixMap, the colors
  20.                 may not be as you expect.  
  21.     
  22.                 To see an example of this there are two 8-bit images included with this snippet.
  23.                 One is a spectral ramp, the other a green/brow ramp.  Both have approx 120 or so colors.
  24.                 to see an example of what PUP may report if you didnt set the colors for a window up
  25.                 properly before displaying open one of the files with the "use picture palette" item 
  26.                 from the palette menu toggled off.
  27.     
  28.                 in this case it will use the "wrong" set of colors to try to draw the image (it just uses
  29.                 what ever the default system color table is).  If you get PUP to sample (by toggling on
  30.                 the "use picture palette" item from the palette menu the picture is rendered correctly.
  31.                 
  32.  
  33.     Written by: Nick Thompson    
  34.  
  35.     Copyright:    Copyright © 1994-1999 by Apple Computer, Inc., All Rights Reserved.
  36.  
  37.                 You may incorporate this Apple sample source code into your program(s) without
  38.                 restriction. This Apple sample source code has been provided "AS IS" and the
  39.                 responsibility for its operation is yours. You are not permitted to redistribute
  40.                 this Apple sample source code as "Apple sample source code" after having made
  41.                 changes. If you're going to re-distribute the source, we require that you make
  42.                 it clear in the source that the code was descended from Apple sample source
  43.                 code, but that you've made changes.
  44.  
  45.     Change History (most recent first):
  46.                 7/14/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  47.                 
  48.  
  49. */
  50.  
  51. /* Constant Declarations */
  52. #include <menus.h>
  53. #include <PictUtils.h>
  54. #include <QDOffScreen.h>
  55. #include <StandardFile.h>
  56. #include <Fonts.h>
  57. #include <Windows.h>
  58. #include <Dialogs.h>
  59. #include <TextEdit.h>
  60. #include <DiskInit.h>
  61. #include <ToolUtils.h>
  62. #include <Devices.h>
  63.  
  64.  
  65.  
  66. #define    WWIDTH        470
  67. #define    WHEIGHT        330
  68.  
  69. #define WLEFT        (((screenBits.bounds.right - screenBits.bounds.left) - WWIDTH) / 2)
  70. #define WTOP        (((screenBits.bounds.bottom - screenBits.bounds.top) - WHEIGHT) / 2)
  71.  
  72. #define HiWrd(aLong)    (((aLong) >> 16) & 0xFFFF)
  73. #define LoWrd(aLong)    ((aLong) & 0xFFFF)
  74.  
  75.  
  76.  
  77. enum {
  78.     mApple = 128,
  79.     mFile,
  80.     mPalette
  81. } ;
  82.  
  83. enum {
  84.     iAbout = 1
  85. } ;
  86. enum {
  87.     iOpen = 1,
  88.     iClose,
  89.     iUnused1,
  90.     iQuit = 4
  91. } ;
  92.  
  93. enum {
  94.     iUsePictPalette = 1
  95. } ;
  96.  
  97. static Boolean gQuitFlag = false ;
  98. static Point gStaggerPos = {50,50} ;
  99. static Boolean gUsePictPalette = true ;
  100.  
  101. // function prototypes
  102.  
  103. void InitToolbox( void ) ;
  104. void MainEventLoop( void ) ;
  105. void HandleKeyPress(EventRecord *event) ;
  106. void HandleOSEvent(EventRecord *event) ;
  107. void HandleMenuCommand(long menuResult) ;
  108. PicHandle DoReadPICT( short theRef, OSErr *theErr ) ;
  109. OSErr DoCreateWindow( PicHandle thePicture ) ;
  110. void AdjustMenus( void ) ;
  111.  
  112.  
  113. const RGBColor    kRGBBlack = {0, 0, 0};
  114. const RGBColor    kRGBWhite = {0xFFFF, 0xFFFF, 0xFFFF};
  115.  
  116.  
  117. void main()
  118. {
  119.     InitToolbox() ;
  120.     
  121.     MainEventLoop();
  122. }
  123.  
  124.  
  125.  
  126. void InitToolbox()
  127. {
  128.     Handle        menuBar = nil;
  129.  
  130.  
  131.  
  132.     InitGraf((Ptr) &qd.thePort);
  133.     InitFonts();
  134.     InitWindows();
  135.     InitMenus();
  136.     TEInit();
  137.     InitDialogs(0L);
  138.     InitCursor();
  139.  
  140.     // initialize application globals
  141.     
  142.     gQuitFlag = false;
  143.     
  144.     
  145.     menuBar = GetNewMBar(128);                // Read menus into menu bar, MBAR res id is 128
  146.     
  147.     if ( menuBar == nil )
  148.          ExitToShell();                        // if we dont have it then quit - your app 
  149.                                              // needs a dialog here
  150.  
  151.     SetMenuBar(menuBar);                    // Install menus
  152.     DisposeHandle(menuBar);
  153.     
  154.     AppendResMenu(GetMenuHandle(mApple), 'DRVR');    // Add DA names to Apple menu, ID 128
  155.  
  156.     DrawMenuBar();
  157. }
  158.  
  159.  
  160. void MainEventLoop()
  161. {
  162.     EventRecord     event;
  163.     WindowPtr       window;
  164.     short           thePart;
  165.     Rect            screenRect;
  166.     Point            aPoint = {100, 100};
  167.     GWorldPtr        theNewWorld ;
  168.     PixMapHandle    offPixMap ;
  169.     GrafPtr            oldPort ;
  170.  
  171.     while( !gQuitFlag )
  172.     {
  173.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  174.         {
  175.             AdjustMenus() ;
  176.  
  177.             switch (event.what) {
  178.                 case mouseDown:
  179.                 
  180.                     thePart = FindWindow( event.where, &window );
  181.                     
  182.                     switch( thePart ) {
  183.                         case inMenuBar: 
  184.                             HandleMenuCommand(MenuSelect(event.where));
  185.                             break;
  186.                         
  187.                         case inDrag:
  188.                     
  189.                             screenRect = (**GetGrayRgn()).rgnBBox;
  190.                             DragWindow( window, event.where, &screenRect );
  191.                             break ;
  192.                     
  193.                         case inContent:
  194.                     
  195.                             if (window != FrontWindow())
  196.                                 SelectWindow( window );
  197.                             break ;
  198.                     
  199.                         case inGoAway:
  200.                             if (TrackGoAway( window, event.where )) {
  201.                                 DisposeWindow ( window );
  202.                             }
  203.                             break ;
  204.                             
  205.                         default:
  206.                             break ;
  207.                     }
  208.                     break ;
  209.                             
  210.                         
  211.                 case updateEvt:
  212.                 
  213.                     window = (WindowPtr)event.message;
  214.                     GetPort(&oldPort ) ;    
  215.                     SetPort( window );
  216.                     
  217.                     BeginUpdate( window );
  218.                     
  219.                     // get the GWorld from the window refcon
  220.                     theNewWorld = (GWorldPtr)GetWRefCon ( window );
  221.                     offPixMap = GetGWorldPixMap( theNewWorld ) ;
  222.                     (void) LockPixels( offPixMap ) ;
  223.                     CopyBits( &((GrafPtr)theNewWorld)->portBits,
  224.                               &window->portBits,
  225.                               &window->portRect,
  226.                               &window->portRect,
  227.                               srcCopy,
  228.                               nil ) ;
  229.                     (void) UnlockPixels( offPixMap ) ;
  230.  
  231.                     EndUpdate( window );
  232.                     SetPort( oldPort ) ;
  233.                     break ;
  234.                     
  235.                 case keyDown:
  236.                 case autoKey:
  237.                     HandleKeyPress(&event);
  238.                     break;
  239.                     
  240.                 case diskEvt:
  241.                     if ( HiWrd(event.message) != noErr ) 
  242.                         (void) DIBadMount(aPoint, event.message);
  243.                     break;
  244.                     
  245.                 case osEvt:
  246.                 case activateEvt:
  247.                     break;
  248.  
  249.  
  250.             }
  251.         }
  252.     }
  253. }
  254.  
  255.  
  256. void HandleKeyPress(EventRecord *event)
  257. {
  258.     char    key;
  259.  
  260.     key = event->message & charCodeMask;
  261.     
  262.     // just check to see if we want to quit...
  263.     
  264.     if ( event->modifiers & cmdKey ) {        /* Command key down? */
  265.         HandleMenuCommand(MenuKey(key));
  266.     } 
  267. }
  268.  
  269.  
  270. void HandleMenuCommand(long menuResult)
  271. {
  272.     short        menuID;
  273.     short        menuItem;
  274.     Str255        daName;
  275.     DialogPtr    theDialog ; 
  276.     short        itemHit ;
  277.     SFTypeList    myTypes = { 'PICT' } ;
  278.     PicHandle    thePicture ;
  279.     OSErr        err ;
  280.     short        theRef ;
  281.     
  282.     StandardFileReply    theSFReply ;
  283.  
  284.     menuID = HiWord(menuResult);
  285.     menuItem = LoWord(menuResult);
  286.     switch ( menuID ) {
  287.         case mApple:
  288.             switch ( menuItem ) {
  289.                 case iAbout:
  290.                     theDialog = GetNewDialog ( 128, nil, (WindowPtr)-1 );
  291.                     do {
  292.                         ModalDialog ( nil, &itemHit );
  293.                     } while( itemHit != ok ) ;
  294.                     DisposeDialog ( theDialog );
  295.                     break;
  296.                     
  297.                 default:
  298.                     GetMenuItemText(GetMenuHandle(mApple), menuItem, daName);
  299.                     (void) OpenDeskAcc(daName);
  300.                     break;
  301.             }
  302.             break;
  303.         case mFile:
  304.             switch ( menuItem ) {
  305.                 case iOpen:
  306.                     // Get the file name to open
  307.                     StandardGetFile( nil, 1, myTypes, &theSFReply ) ;
  308.                     
  309.                     // did the user cancel?
  310.                     if(!theSFReply.sfGood)
  311.                         break ;
  312.                     
  313.                     // open the file
  314.                     err = FSpOpenDF( &theSFReply.sfFile, fsRdPerm, &theRef ) ;
  315.                     
  316.                     if( err != noErr )
  317.                         break ;     // should handle this properly
  318.                         
  319.                     thePicture = DoReadPICT( theRef, &err ) ;
  320.                     
  321.                     if( err != noErr )
  322.                         break ;     // should handle this properly
  323.                 
  324.                     // display the contents
  325.                     err = DoCreateWindow( thePicture ) ;
  326.                     
  327.                     break ;
  328.                     
  329.                 case iClose:
  330.                     DisposeWindow ( FrontWindow() );
  331.                     break ;
  332.                 case iQuit:
  333.                     gQuitFlag = true;
  334.                     break;
  335.             }
  336.             break;
  337.             
  338.         case mPalette:
  339.             switch ( menuItem ) {
  340.                 case iUsePictPalette :
  341.                     // toggle the check mark and the global boolean
  342.                     gUsePictPalette = !gUsePictPalette ;
  343.                     CheckItem ( GetMenuHandle ( mPalette ), iUsePictPalette, gUsePictPalette );
  344.                     break ;
  345.             }
  346.             break ;
  347.             
  348.         case 131:
  349.         
  350. //--------------------------- T E S T   R O U T I N E ---------------------------------
  351.             if( menuItem == 1 ) {
  352.                 // get some of the screen
  353.                 PicHandle DumpScreenArea( Rect *area ) ;        // prototype
  354.                 
  355.                 // because I have multiple monitors and I wanted to test on them
  356.                 // I set up the area below, you may want something rather different
  357.                 // YOU WILL PROBABLY NEED TO CHANGE THIS
  358.                 
  359.                 Rect area = { 0, -50, 200, 200 } ;                // area to save 
  360.  
  361.                 thePicture = DumpScreenArea( &area ) ;
  362.                 
  363.                 if( thePicture != nil )
  364.                     err = DoCreateWindow( thePicture ) ;
  365. //--------------------------- T E S T   R O U T I N E ---------------------------------
  366.  
  367.             }
  368.             break; 
  369.  
  370.     }
  371.     HiliteMenu(0);        // Unhighlight whatever MenuSelect or MenuKey hilited
  372. }
  373.  
  374. void AdjustMenus( void ) 
  375. {
  376.     WindowPtr    theWindow ;
  377.     theWindow = FrontWindow() ;
  378.     if( theWindow != nil ) {
  379.         EnableItem ( GetMenuHandle ( mFile ), iClose );
  380.     }
  381.     else {
  382.         DisableItem ( GetMenuHandle ( mFile ), iClose );
  383.     }
  384.     // make sure the check marks are correct
  385.     CheckItem ( GetMenuHandle ( mPalette ), iUsePictPalette, gUsePictPalette );
  386. }
  387.  
  388. PicHandle DoReadPICT( short theRef, OSErr *theErr ) 
  389. {
  390.     long        theFileSize ;
  391.     PicHandle    thePicture ;
  392.     
  393.     // pict files have a 512 byte header at the front - we dont care about this
  394.     // we can find the size of the pict by subtracting 512 bytes from the length
  395.     // of the file.  We then want to resize the handle to that and read the data
  396.     // into the resized handle.
  397.     
  398.     if(( *theErr = GetEOF( theRef, &theFileSize )) != noErr ) {
  399.         FSClose( theRef ) ;
  400.         return nil ; 
  401.     }
  402.     
  403.     if(( *theErr = SetFPos( theRef, fsFromStart, 512)) != noErr ) {
  404.         FSClose( theRef ) ;
  405.         return nil ; 
  406.     }
  407.  
  408.     theFileSize -= 512 ;
  409.     
  410.     thePicture = (PicHandle)NewHandle( theFileSize ) ;
  411.     if( thePicture == nil ) {
  412.         FSClose( theRef ) ;
  413.         *theErr = MemError() ;
  414.         return nil ;         // what ever the mem manager error was
  415.     }
  416.     
  417.     HLock( (Handle)thePicture ) ;
  418.     *theErr = FSRead( theRef, &theFileSize, (Ptr)*thePicture ) ;
  419.     HUnlock(  (Handle)thePicture ) ;
  420.     
  421.     if( *theErr != noErr ) {
  422.         FSClose( theRef ) ;
  423.         return nil ; 
  424.     }
  425.  
  426.     return thePicture ;    
  427. }
  428.  
  429. OSErr DoCreateWindow( PicHandle thePicture )
  430. {
  431.  
  432.     Rect        theRect ;
  433.     OSErr        theErr ;
  434.     GWorldPtr    theNewWorld ;
  435.     CGrafPtr    savedPort ;
  436.     WindowPtr    theWindow ;
  437.     GDHandle    oldDevice ;
  438.     
  439.     PictInfo        thePictInfo ;
  440.     PaletteHandle    thePictPalette = nil ;
  441.     CTabHandle        thePictCTab = nil ;
  442.     
  443.     // make an offscreen environment and image the pict into this
  444.     // Make a window the size of the pict
  445.     // store a reference to the GWorld in the Refcon of the window
  446.     // invalidate the window content area.
  447.     
  448.     theRect = (**thePicture).picFrame;
  449.     
  450.     // to we want to attempt to sample the picture... 
  451.     if( gUsePictPalette ) {
  452.     
  453.         // use the picture utilities to get the palette for the window
  454.         theErr = GetPictInfo( thePicture, &thePictInfo, returnColorTable, 256, systemMethod, 0) ;
  455.         
  456.         // set up the palette and color table for later use
  457.         thePictPalette = NewPalette( 256, thePictInfo.theColorTable, pmTolerant, 0x1000 ) ;
  458.         thePictCTab = thePictInfo.theColorTable ;
  459.     }
  460.     
  461.     // we are only dealing with eight bit images here
  462.     // hence the requirement for the picture utils package to 
  463.     // return 256 colors, and we will create a gWorld 8 bits deep
  464.     
  465.     theErr = NewGWorld( &theNewWorld, 8, &theRect, thePictCTab, nil, 0L ) ;
  466.     
  467.     if( theErr != noErr ) 
  468.         return theErr ;
  469.     
  470.     // save the world
  471.     GetGWorld( &savedPort, &oldDevice ) ;
  472.     SetGWorld( theNewWorld, nil ) ;
  473.     
  474.     
  475.     RGBForeColor( &kRGBBlack ) ;        // ensure the fg and bg colors are 
  476.     RGBBackColor( &kRGBWhite ) ;        // as anticipated
  477.     EraseRect( &theRect ) ;                // clear the area for the pict
  478.     PenMode( srcCopy ) ;                // ensure the t/f mode is as expected
  479.  
  480. SetOrigin( theRect.left, theRect.top );
  481.  
  482.     // render the image into the offscreen buffer
  483.     DrawPicture( thePicture, &theRect ) ;
  484. SetOrigin( 0, 0 );
  485.     
  486.     SetGWorld( savedPort, oldDevice ) ;
  487.     
  488.     // create the window
  489.     OffsetRect( &theRect, gStaggerPos.h, gStaggerPos.v) ;
  490.     gStaggerPos.h += 16 ;
  491.     gStaggerPos.v += 16 ;        // heh - should roll these around, but you wont 
  492.                                 // create more than a couple of windows, will you  :-)
  493.                                  
  494.     theWindow  = NewCWindow( nil, &theRect, "\pplayTime", true, 
  495.                                 documentProc, (WindowPtr)-1, true, (long)theNewWorld );    
  496.                 
  497.     // and if we set up the palette earlier assign it to the window                
  498.     if( thePictPalette != nil ) {
  499.         SetPalette ( theWindow, thePictPalette, true );
  500.     }
  501.     
  502.     ActivatePalette ( theWindow );    
  503.     
  504.     // make sure it is visible
  505.     ShowWindow( theWindow ) ;
  506.     
  507.     SetGWorld( (CGrafPtr)theWindow, nil ) ;
  508.     
  509.     // invalidate the content region of the window - we don't do any drawing to it here.
  510.     InvalRect ( &theRect );
  511.     
  512.     SetGWorld( savedPort, oldDevice ) ;
  513.     return noErr;
  514. }